#include "SingleLinkedList.h"

void simpleTest();
void errorTest();
void createTest();
void insertTest();
void findTest();
void updateTest();
void removeTest();

int main()
{
    simpleTest();
    //errorTest();
    return 0;
}

void simpleTest()
{
    createTest();
    insertTest();
    findTest();
    updateTest();
    removeTest();
}
void errorTest(){
    pushBack(nullptr, 1);
    //insertAfter(nullptr, nullptr, 1);
    //removeAfter(nullptr, nullptr);
    //update(nullptr, 1);
}

void removeTest()
{
    SingleLinkedList *sl = newSingleLinkedList();
    int arr[] = {1, 2, 3};
    for (int i = 0; i < 3; i++)
    {
        pushBack(sl, arr[i]);
    }
    removeAfter(sl, sl->head->next); //{1,3}
    assertTrue(sl->size == 2);
    assertTrue(sl->head->next->val == 1);
    assertTrue(sl->head->next->next->val == 3);
    assertTrue(sl->tail->val == 3);

    removeAfter(sl, sl->head->next); //{1}
    assertTrue(sl->size == 1);
    assertTrue(sl->head->next->val == 1);
    assertTrue(sl->tail->val == 1);

    removeAfter(sl, sl->head); //{}
    assertTrue(sl->size == 0);
    assertTrue(sl->tail == nullptr);
    destroy(sl);
}

void updateTest()
{
    SingleLinkedList *sl = newSingleLinkedList();
    int arr[] = {1, 2, 3};
    for (int i = 0; i < 3; i++)
    {
        pushBack(sl, arr[i]);
    }

    update(find(sl, 2), -1);
    update(find(sl, 3), -2);
    update(find(sl, 1), -3);

    assertTrue(sl->head->next->val == -3);
    assertTrue(sl->head->next->next->val == -1);
    assertTrue(sl->head->next->next->next->val == -2);

    destroy(sl);
}

void findTest()
{
    SingleLinkedList *sl = newSingleLinkedList();
    int arr[] = {1, 2, 3};
    for (int i = 0; i < 3; i++)
    {
        pushBack(sl, arr[i]);
    }
    assertTrue(find(sl, 1) == sl->head->next);
    assertTrue(find(sl, 2) == sl->head->next->next);
    assertTrue(find(sl, 3) == sl->head->next->next->next);
    destroy(sl);
}

void insertTest()
{
    SingleLinkedList *sl = newSingleLinkedList();
    int v1 = 10;
    insertAfter(sl, sl->head, v1);
    assertTrue(sl->size == 1);
    assertTrue(sl->head->next->val == v1);
    assertTrue(sl->tail->val == v1);
    int v2 = 20;
    pushBack(sl, v2);
    assertTrue(sl->size == 2);
    assertTrue(sl->head->next->next->val == v2);
    assertTrue(sl->tail->val == v2);
    int v3 = 30;
    insertAfter(sl, sl->head->next, v3);
    assertTrue(sl->size == 3);
    DynamicArray *nodeVlues = newDynamicArray(sl->size);
    SingleLinkedListNode *node = sl->head->next;
    while (node != nullptr)
    {
        insert(nodeVlues, nodeVlues->size, node->val);
        node = node->next;
    }
    int excepted[] = {v1, v3, v2};
    assertArrayEquals(excepted, nodeVlues->datas, sl->size);
    destroy(nodeVlues);
    destroy(sl);
}

void createTest()
{
    SingleLinkedList *sl = newSingleLinkedList();
    assertTrue(sl->size == 0);
    destroy(sl);
}